package golf.stockdata.framework.batch;

import golf.stockdata.framework.batch.dataobject.JobStepData;
import golf.stockdata.framework.common.ApplicationConstant;
import golf.stockdata.framework.spring.ApplicationObjectContainer;
import golf.stockdata.framework.spring.ApplicationServiceProcessor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;

public class JobProcessor implements org.quartz.Job {
	
	private static Logger logger = Logger.getLogger(JobProcessor.class);

	@SuppressWarnings("unchecked")
	public void execute(JobExecutionContext context) throws JobExecutionException {
		
		logger.debug(">>> execute");

		JobKey jobKey = context.getJobDetail().getKey();
		logger.info(jobKey + " is executing");
		ArrayList<JobStepData> jobStepsData = (ArrayList<JobStepData>) context.getJobDetail().getJobDataMap()
				.get(ApplicationConstant.JOB_STEP_DATA);

		for (JobStepData jobStepData : jobStepsData) {

			if(logger.isDebugEnabled()){
				logger.debug("=======================================");
				logger.debug("Jobstep : " + jobStepData.getName());
				logger.debug("Type    : " + jobStepData.getType());
				logger.debug("Class   : " + jobStepData.getClassName());
				logger.debug("Command : " + jobStepData.getCommand());
				logger.debug("Parameters : ");
				Iterator<String> strItr = jobStepData.getParameters().keySet().iterator();
				while (strItr.hasNext()) {
					String c = strItr.next();
					logger.debug("         key: " + c + ", value: "+ jobStepData.getParameter(c));
				}
				logger.debug("=======================================");
			}

			if (jobStepData.getType() == null || jobStepData.getType().equalsIgnoreCase("java")) {
				
				ApplicationObjectContainer aoc = ApplicationServiceProcessor.getAOC();
				
				try{
//					Class<?> aClass = Class.forName(jobStepData.getClassName());
					
					Job jobInstance = (Job) aoc.getAbility(jobStepData.getClassName());
					
					if(!jobInstance.isIntialized()){
						jobInstance.initializeJob((HashMap<String, String>) jobStepData.getParameters());
					}
					jobInstance.execute();
					
				}catch(Exception e){
					logger.error(e);
					if(logger.isDebugEnabled()){
						StringWriter stack = new StringWriter();
						e.printStackTrace(new PrintWriter(stack));
						logger.debug(stack.toString());
					}
				}finally{
					aoc.release();
				}

			} else if (jobStepData.getType().equalsIgnoreCase("command")) {

				StringBuilder cmdLine = new StringBuilder(jobStepData.getCommand());
				Iterator<String> strItr = jobStepData.getParameters().keySet().iterator();
				while (strItr.hasNext()) {
					cmdLine.append(" ");
					cmdLine.append(jobStepData.getParameter(strItr.next()));
				}
				try {
					Process p = Runtime.getRuntime().exec(cmdLine.toString());
					p.waitFor();
					BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
					String line = reader.readLine();
					while (line != null) {
						System.out.println(line);
						line = reader.readLine();
					}
				} catch (IOException e) {
					logger.error(e);
					if(logger.isDebugEnabled()){
						StringWriter stack = new StringWriter();
						e.printStackTrace(new PrintWriter(stack));
						logger.debug(stack.toString());
					}
				} catch (InterruptedException e) {
					logger.error(e);
					if(logger.isDebugEnabled()){
						StringWriter stack = new StringWriter();
						e.printStackTrace(new PrintWriter(stack));
						logger.debug(stack.toString());
					}
				}
			}

		}
		
		logger.debug("<<< execute");

	}

}
